﻿using ScFramework.Core;
using System.Collections;
using System.Collections.Generic;
using System;
using UnityEngine;

public class LogicClient :LogicModuleBase<MessageManager,LocalServer>,INeedEntityData
{

    List<MeshEntityData> meshEntityDatas;
    List<EntityChangeArgs> _queue;
    [RegisterEvent(EntityDataReq.Create)]
    public void  SetListenToCreate(EntityCreateArgs args)
    {
        _queue.Add(new EntityChangeArgs(args));
    }

    [RegisterEvent(EntityDataReq.Create)]

    public void SetListenToCreate(EntityCreateWithActionArgs args)
    {
        _queue.Add(new EntityChangeArgs(args));
    }
    [RegisterEvent(EntityDataReq.Delete)]
    public void SetListenToDelete(EntityDeleteArgs args)
    {
        _queue.Add(new EntityChangeArgs(args));
    }
    void SendMsg()
    {
        var ans = new List<EntityChangeArgs>(_queue);
        _queue.Clear();
        if (ans.Count > 0)
        {
            SysModule.Get<LocalServerEntityDataEvent>().DispatchMessage(LocalServerEntityDataEvent.FromLogics, this, new EntityDataReqArgs { messages = ans });
        }
    }
    public override void FixedUpdate()
    {
        base.FixedUpdate();
        SendMsg();
    }
    public override void OnEnable()
    {
        base.OnEnable();
        SysModule1.InitData(this);
        if (this is INeedEntityData)
        {
            SysModule.Get<LocalServerEntityDataEvent>().RegisterHandler(LocalServerEntityDataEvent.ToLogics, (object sender, EventArgs a) =>
            {
                if (a is EntityDataLocalArgs e)
                {
                    var I = this as INeedEntityData;
                    bool flag = false;
                    List<ValueChangeArgs> list = new List<ValueChangeArgs>();
                    foreach (var x in e.messages)
                    {
                        if (x.ChangeType == EntityChangeType.Created)
                        {
                            I.OnEntityCreate((x.Args as EntityCreatedArgs).Data);
                            flag = true;
                        }
                        else if (x.ChangeType == EntityChangeType.Delete)
                        {
                            I.OnEntityDestory((x.Args as EntityDeleteArgs).EntityID);
                            flag = true;
                        }
                        else if (x.ChangeType == EntityChangeType.ValueChange)
                        {
                            var args = x.Args as ValueChangeArgs;
                            list.Add(args);
                            if (meshEntityDatas.Find(s => s.ID == args.EntityID) != null) 
                            {
                                flag = true;
                            }
                        }
                        else
                        {
                            throw new Exception();
                        }
                    }
                    if (list.Count > 0)
                    {
                        I.OnEntitValueChange(list);
                    }
                    if (flag)
                    {
                        Dispatch(LogicEntityDataEvent.Receive_Data, meshEntityDatas.ConvertAll(s => s));
                    }
                }
                else throw new Exception();
                return null;
            });
        }
        else throw new Exception();
        _queue = new List<EntityChangeArgs>();
    }


    public override void OnDisable()
    {
        base.OnDisable();
        SysModule.RemoveAbout(this);
        SendMsg();
        _queue = null;
        meshEntityDatas = null;
    }
    public void InitData(List<EntityData> datas)
    {
        meshEntityDatas = new List<MeshEntityData>();
        foreach (var x in datas)
        {
            if (x.GetComponentData<SComBody>() != null)
            {
                OnEntityCreate(x);
            }
        }
        Dispatch(LogicEntityDataEvent.Receive_Data, meshEntityDatas.ConvertAll(s => s), false);
    }

    public void OnEntityDestory(ushort entityID)
    {
        if (meshEntityDatas.Find(s => s.ID == entityID) != null)
        {
            meshEntityDatas.RemoveAll(s => s.ID == entityID);
        //    Dispatch(LogicEntityDataEvent.Receive_Data, meshEntityDatas.ConvertAll(s => s), false);
        }
    }

    public void OnEntityCreate(EntityData data)
    {
        Debug.Assert(meshEntityDatas != null);
        if (data.GetComponentData<SComBody>() == null)
        {
            return;
        }
        meshEntityDatas.UniqueAdd(new MeshEntityData
        {
            Name = data.GetEntityName(),
            ID = data.EntityIdentity.right(),
            //Transform = new STransformVEx(data.GetComponentData<STransform>()),
            Body = new SComBodyVEx(data.GetComponentData<SComBody>()),
            Values = new SComValuesVEx(data.GetComponentData<SComValues>()),
            Colliders = data.GetComponentDatas<SCollider>().ConvertAll(s => new SColliderVEx(s)),
            Funcs = data.GetComponentDatas<SFuncBase>().ConvertAll(s => new SFuncBaseVEx(s))
        }) ;
    //    Dispatch(LogicEntityDataEvent.Receive_Data, meshEntityDatas.ConvertAll(s => s), false);
    }

    public void OnEntitValueChange(List<ValueChangeArgs> args)
    {
    //    if(meshEntityDatas.Find(s=>args.Find(a=>a.EntityID==s.ID)!=null)!=null)
    //    Dispatch(LogicEntityDataEvent.Receive_Data, meshEntityDatas.ConvertAll(s => s), false);
    }
}

public enum LogicEntityDataEvent
{
    Receive_Data
}
public class MeshEntityData
{
    public string Name;
    public ushort ID;
    public ItemType itemType;
//    public STransformVEx Transform;
    public SComBodyVEx Body;
    public SComValuesVEx Values;
    public List<SFuncBaseVEx> Funcs;
    public List<SColliderVEx> Colliders;
}